package com.example.blog.aop;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.blog.controller.BaseController;
import com.example.blog.domain.ChangelogServer;
import com.example.blog.domain.Response;
import com.example.blog.domain.WebsiteAdministration;
import com.example.blog.exception.BusinessException;
import com.example.blog.note.LogInfo;

import com.example.blog.service.ChangelogServerService;
import com.example.blog.service.WebsiteAdministrationService;
import com.example.blog.utils.IpUtil;
import com.example.blog.utils.JwtUtils;
import com.example.blog.utils.RedisStorage;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Aspect  //说明该对象是一个切面
@Component
@Order(2)
@Slf4j
public class CustomizationAop extends BaseController {
    private final Ip2regionSearcher ip2regionSearcher;
    private final RedisStorage redisStorage;

    @Autowired
    public CustomizationAop(Ip2regionSearcher ip2regionSearcher,
                            RedisStorage redisStorage) {
        this.ip2regionSearcher = ip2regionSearcher;
        this.redisStorage = redisStorage;

    }

    //记录除消息外的日志
    @Around("@annotation(logInfo)")
    public Object operate(ProceedingJoinPoint joinPoint, LogInfo logInfo) throws Throwable {
        Object proceed = null;
        try{
            HttpServletRequest request = getHttpInfo();
            String ip = IpUtil.getIpAddress(request);
            redisStorage.checkIpAccess(ip); //检查IP是否非法
            IpInfo ipInfo = ip2regionSearcher.memorySearch(ip);
            proceed = joinPoint.proceed();
            Response proceeds = (Response) proceed;
            printLogInfo(logInfo.value(), request, joinPoint, ip, ipInfo != null ? ipInfo.getAddress() : "未知", Calendar.getInstance(), proceeds.getData());
        }catch (Exception e){
            throw new BusinessException(Response.ERROR_CODE,logInfo.value(),e);
        }
         return proceed;
    }


    public static void printLogInfo(String info, HttpServletRequest request, JoinPoint joinPoint, String ip, String address, Calendar date, Object data) {
        Claims claims = JwtUtils.checkToken(request.getHeader("token"));
        String resultData = null;
        if (data instanceof ArrayList) {
            //去除空格  换行  制表符
            resultData = ((ArrayList<?>)data).toString().replaceAll("\\s*|\r|\n|\t", "");

        }else {
            resultData = String.valueOf(data);
        }
        log.info("{}  请求路径：{}  包/类·方法：{} ===》{}  参数：{}  用户名/用户ID：{}  访问IP：{}  {}  耗时：{}毫秒  返回数据：{}",
                info,
                request.getRequestURL().toString(),
                joinPoint.getTarget().getClass().getName(),
                joinPoint.getSignature().getName(),
                joinPoint.getArgs().length > 0 ? Arrays.toString(joinPoint.getArgs()) : null,
                claims != null ? String.valueOf(claims.get("uid")) : "游客",
                address,
                ip,
                (Calendar.getInstance().getTimeInMillis() - date.getTimeInMillis()),
                resultData);
    }
}
